package de.tabuma.formcreator.formstructur.logik;

import de.tabuma.formcreator.formstructur.logik.FormStructurWithComplexTypeFactory;
import de.tabuma.soap.logik.SoapFacade;
import de.tabuma.formcreator.entity.*;
import de.tabuma.formcreator.entity.*;

import de.tabuma.soap.*;
import de.tabuma.soap.logik.*;
import de.tabuma.soap.entity.wsdl.*;
import de.tabuma.soap.entity.xsd.*;

import java.util.*;
import java.util.logging.*;
import javax.xml.namespace.QName;

/**
  * @author $Author: $
  * @version $Revision: $
  * @since $Date: $
 */
public class FormStrukturFactory {

    private final static Logger log = Logger.getLogger(FormStrukturFactory.class.getName());

    public static FormStructur createFormularStruktur(TDefinitions wsdl,List<TPart> parts,String type,String name) {
        FormStructur formularStruktur = new FormStructur(name, type, 1, 1, false, false, false, false);
        FormStructur simpleTypes = new FormStructur(name, type, 1, 1, false, false, false, false);
        log.fine("parts:"+parts.size());
        for(int i=0;i<parts.size();i++) {
            log.fine("part:"+parts.get(i).getName());
            if(parts.get(i)!=null) {
                FormStructur formularStruktur1 = createFormularStruktur(wsdl,parts.get(i));
                if(!formularStruktur1.isSimpleType()) {
                    formularStruktur1.setHeadStructur(formularStruktur);
                    formularStruktur.addFormularStruktur(formularStruktur1);
                }
                else {
                    formularStruktur1.setHeadStructur(simpleTypes);
                    simpleTypes.addFormularStruktur(formularStruktur1);
                }
            }
        }
        if(simpleTypes.getFormStructur().size()>0) {
            simpleTypes.setHeadStructur(formularStruktur);
            formularStruktur.addFormularStruktur(simpleTypes);
        }

        return formularStruktur;
    }

    public static FormStructur createFormularStrukturFromObject(QName qname, TDefinitions wsdl, String operationName) {
        log.fine("start function");
        TMessage message = SoapFacade.getMessage(wsdl, qname.getLocalPart());
        log.fine("finish loading message");
        List<Long> partList = message.getPart();
        List<TPart> partList1 = new ArrayList<TPart>();
        for(int i=0;i<partList.size();i++) {
            TPart part = PMF.get(partList.get(i), new TPart());
            partList1.add(part);
            log.fine("part: "+part.getName());
        }
        log.fine("finish adding all parts");
        FormStructur formularStruktur = createFormularStruktur(wsdl, partList1, operationName, operationName+" Anfrage");
        log.fine("finish creating FormularStruktur");
        formularStruktur.createBreadcrumps(new ArrayList<FormStructur>());
        log.fine("finish creating breadcrumps");
        return formularStruktur;
    }

    public static FormStructur createFormularStrukturAsRequestObjekt(TDefinitions wsdl, String operationName) {
        String qnameString = SoapFacade.getInputParameter(wsdl, operationName);
        String split[] = qnameString.split(":");
        QName qname = new QName("",split[1],split[0]);
        return createFormularStrukturFromObject(qname,wsdl,operationName);
        
    }

    public static FormStructur createFormularStrukturAsResponseObjekt(TDefinitions wsdl, String operationName) {
        String qnameString = SoapFacade.getOutputParameter(wsdl, operationName);
        String split[] = qnameString.split(":");
        QName qname = new QName("",split[1],split[0]);
        return createFormularStrukturFromObject(qname,wsdl,operationName);
    }

    public static FormStructur createFormularStrukturAsDefaultOjbect(TDefinitions wsdl, String operationName) {
        String qnameString = SoapFacade.getDefaultParameter(wsdl, operationName);
        if(qnameString!=null) {
            String split[] = qnameString.split(":");
            QName qname = new QName("",split[1],split[0]);
            return createFormularStrukturFromObject(qname,wsdl,operationName);
        }
        else {
            return null;
        }
    }

    public static FormStructur createFormularStruktur(TDefinitions wsdl,TPart tpart) {
        FormStructur formularStruktur = null;
        
        if(tpart.getType()==null) {
            return createFormularStrukturWithElements(wsdl,tpart);
        }

        String datentype = "";
        if(tpart.getElement()!=null) {
            String split[] = tpart.getElement().split(":");
            QName elementQName = new QName("",split[1],split[0]);
            datentype = elementQName.getLocalPart();
        }
        else {
            String split[] = tpart.getType().split(":");
            QName typeQName = new QName("",split[1],split[0]);
            datentype = typeQName.getLocalPart();
        }
        formularStruktur = new FormStructur(tpart.getName(), datentype, 1, 1, false, false,false,false);

        log.fine("formularStruktur:"+formularStruktur.getName()+"/simpleType:"+formularStruktur.isSimpleType());

        if(!formularStruktur.isSimpleType()) {
            //KomplexErzeugen!
            List<XsSchema> schemaList = SchemaFacade.getSchema(wsdl);
            List<XsComplexType> complexTypeList = SoapFacade.getComplexType(schemaList);
            for(int i=0;i<complexTypeList.size();i++) {
                XsComplexType xsComplexType = complexTypeList.get(i);
                if(xsComplexType.getName().equals(datentype)) {
                    formularStruktur = FormStructurWithComplexTypeFactory.createFormularStruktur(wsdl, xsComplexType, tpart.getName() , 1, 1);
                    return formularStruktur;
                }
            }
        }
        return formularStruktur;
    }

    public static FormStructur createFormularStrukturWithElements(TDefinitions wsdl, TPart part) {
        log.fine("parts:"+part.getName());
        QName qnamePart = new QName(part.getElement());
        log.fine("QName-Parts:"+qnamePart);
        List<XsSchema> schemaList = SchemaFacade.getSchema(wsdl);
        log.fine("XSSchema count:"+schemaList.size());
        List<XsElement> elementList = SoapFacade.getElement(schemaList);
        log.fine("XSElements count:"+elementList.size());
        for(int i=0;i<elementList.size();i++) {
            XsElement xsElement = elementList.get(i);
            log.fine(xsElement.getName()+"/"+qnamePart.getLocalPart());
            if(qnamePart.getLocalPart().indexOf(xsElement.getName())!=-1) {

                List<XsComplexType> complexTypeList = SoapFacade.getComplexType(schemaList);
                log.fine("complexTypeList:"+complexTypeList.size());
                for(int j=0;j<complexTypeList.size();j++) {
                    XsComplexType xsComplexType = complexTypeList.get(j);
                    if(xsElement.getType().endsWith(xsComplexType.getName())) {
                        log.fine("xsElement ("+xsElement.getType()+") is equal to "+xsComplexType.getName());
                        return FormStructurWithComplexTypeFactory.createFormularStruktur(wsdl, xsComplexType, part.getName() , 1, 1);
                    }
                }
                log.fine("end of checking complex list");
            }
        }
        return new FormStructur(part.getName(), qnamePart.getLocalPart(), 1, 1, false, false, false, false);
    }
}
